#include "EPSG/Camera.h"

/* EPSG Includes */
#include "EPSG/Transform.h"
#include "EPSG/CameraManager.h"

/* System Includes */
#ifdef WIN32
	#include <Windows.h>
#endif

/* OpenGL Includes */
#include <GL/GL.h>
#include <GL/GLU.h>

EPSG::Camera::Camera()
{
	_fovY = 50.0;
	_up.x = _up.z = 0.0;
	_up.y = 1.0;
	_zNear = 1;
	_zFar = 100;

	EPSG::CameraManager::push( this );
	_cameraTransformRotate = new Transform();
	_cameraTransformTranslate = new Transform();
	_cameraTransformRotate->setParent( _cameraTransformTranslate );
	_parent = _cameraTransformRotate;
}

void EPSG::Camera::setupCamera()
{
	int vp[4];
	glGetIntegerv( GL_VIEWPORT, vp );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	if( vp[2] > vp[3] )
		gluPerspective( _fovY, (float)(vp[2]/vp[3]), _zNear, _zFar );
	else
		gluPerspective( _fovY, (float)(vp[3]/vp[2]), _zNear, _zFar );
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	gluLookAt( _eye.x, _eye.y, _eye.z, 
			   _center.x, _center.y, _center.z,
			   _up.x, _up.y, _up.z );

	_parent->setupCamera();
}

void EPSG::Camera::setActive()
{
	EPSG::CameraManager::setActive( this );
}

void EPSG::Camera::setFovY( float fovY )
{
	_fovY = fovY;
}

void EPSG::Camera::setZPlanes( float zNear, float zFar )
{
	_zNear = zNear;
	_zFar = zFar;
}

void EPSG::Camera::setEye( float x, float y, float z )
{
	_eye.x = x;
	_eye.y = y;
	_eye.z = z;
}

void EPSG::Camera::setEye( Vec3<float> eye )
{
	_eye = eye;
}

void EPSG::Camera::setCenter( float x, float y, float z )
{
	_center.x = x;
	_center.y = y;
	_center.z = z;
}

void EPSG::Camera::setCenter( Vec3<float> center )
{
	_center = center;
}

void EPSG::Camera::setUp( float x, float y, float z )
{
	_up.x = x;
	_up.y = y;
	_up.z = z;
}

void EPSG::Camera::setUp( Vec3<float> up )
{
	_up = up;
}

float EPSG::Camera::getZNear()
{
	return _zNear;
}

float EPSG::Camera::getZFar()
{
	return _zFar;
}

EPSG::Vec3<float> EPSG::Camera::getEye()
{
	return _eye;
}

EPSG::Vec3<float> EPSG::Camera::getCenter()
{
	return _center;
}

EPSG::Node* EPSG::Camera::setParent( EPSG::Group* parent )
{
	return _cameraTransformTranslate->setParent( parent );
}

EPSG::Node* EPSG::Camera::getParent()
{
	return _cameraTransformRotate->getParent();
}

EPSG::Transform* EPSG::Camera::getTransformRotate()
{
	return _cameraTransformRotate;
}

EPSG::Transform* EPSG::Camera::getTransformTranslate()
{
	return _cameraTransformTranslate;
}

void EPSG::Camera::translate( float x, float y, float z )
{
	_cameraTransformTranslate->translate( x, y, z );
}

void EPSG::Camera::rotate( float angle, float x, float y, float z )
{
	_cameraTransformRotate->rotate( angle, x, y, z );
}

void EPSG::Camera::rotate( float x, float y, float z )
{
	_cameraTransformRotate->rotate( x, y, z );
}